Skip to content

Fix/readme#24

Merged
SaschaOnTour merged 31 commits intomainfrom
fix/readme
Apr 26, 2026
Merged

Fix/readme#24
SaschaOnTour merged 31 commits intomainfrom
fix/readme

Conversation

@SaschaOnTour
Copy link
Copy Markdown
Owner

No description provided.

…eceiver resolution

v1.1.0's call_parity check produced ~80% false positives on any realistic
Rust codebase using a Session/Context/Handle pattern (93 of 116 findings
on the rlm reference codebase). Root cause: the receiver-type resolver
could only extract types from direct constructor calls — `let s = T::ctor()` —
and collapsed to `<method>:name` for the more common `let s = T::ctor().
map_err(f)?` and `ctx.field.method()` patterns.

This release rebuilds the resolver around shallow type propagation over
`syn::Expr`, delivered in three layers under `call_parity_rule/type_infer/`:

Stage 1 — core: Return-type propagation (method chains, field access,
Result/Option/Future combinators, pattern bindings for let/if-let/match/
for, `Self::xxx` substitution). Stdlib-combinator table covers `unwrap`,
`expect`, `map_err`, `ok`, `ok_or`, `filter`, `as_ref` etc.; closure-
dependent combinators (`map`, `and_then`) stay unresolved rather than
fabricate an edge.

Stage 2 — trait dispatch: `dyn Trait` / `&dyn Trait` / `Box<dyn Trait>`
receivers fan out to every workspace impl of the trait. Sound over-
approximation that makes call-parity structurally correct for
Ports&Adapters architectures. Turbofish return-type (`get::<Session>()`)
for generic fns.

Stage 3 — framework config: Type-alias expansion, user-configurable
`transparent_wrappers` (Axum `State<T>`, Actix `Data<T>`, …) and
`transparent_macros` config. Starter-pack of 10 common attribute macros
applied by default.

Additive change — no public-API break. Legacy fast-path (direct ctors,
signature params, explicit annotations) stays intact so all v1.1.0 unit-
test fixtures keep working. Bundled bugfix in iosp::analyze_file: Item::
Impl/Trait/Mod now properly inherits file_in_test (previously only Fn did),
which fixes spurious ERROR_HANDLING/MAGIC_NUMBER flags on impl helpers
inside cfg-test files.
Copilot AI review requested due to automatic review settings April 26, 2026 08:51
@SaschaOnTour SaschaOnTour merged commit f304e28 into main Apr 26, 2026
3 checks passed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR overhauls the project documentation by rewriting README.md and adding a “book” set of reference + use-case guides under book/, aimed at explaining rustqual’s dimensions, configuration, suppressions, output formats, and recommended workflows (including CI and AI-agent usage).

Changes:

  • Rewrites README.md into a shorter, book-linked landing page with examples and workflows.
  • Adds comprehensive book/ markdown docs for each dimension/use case plus references (CLI/config/rules/suppressions/output formats).
  • Documents architecture call parity (“adapter parity”) and AI-agent integration patterns.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
book/test-quality.md Documents Test Quality dimension rules (TQ-*), configuration, and CI patterns with coverage.
book/reference-suppression.md Reference for qual:* annotations and suppression/orphan behavior.
book/reference-rules.md Catalog of rule codes grouped by dimension.
book/reference-output-formats.md Reference for --format outputs and example snippets.
book/reference-configuration.md Full rustqual.toml schema documentation and examples.
book/reference-cli.md CLI flag reference and common command compositions.
book/module-quality.md SRP/module-level quality explanation and refactor patterns.
book/legacy-adoption.md Adoption strategies for existing codebases (baseline, suppression, staged enablement).
book/getting-started.md Install + first-run walkthrough and navigation to other docs.
book/function-quality.md IOSP + complexity + structural checks overview with examples.
book/coupling-quality.md Coupling metrics/checks overview and refactor guidance.
book/code-reuse.md DRY/dead-code/boilerplate checks explained with suppression guidance.
book/ci-integration.md CI recipes (diff-only runs, coverage, baseline comparison, SARIF).
book/architecture-rules.md Layers/forbidden/pattern/trait-contract rule documentation.
book/ai-coding-workflow.md AI-agent focused workflow patterns (instructions/hooks/CI/baseline).
book/adapter-parity.md Call-parity (adapter symmetry) explanation and configuration guidance.
README.md New top-level landing page linking into the book and summarizing key differentiators.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

| `json` | Machine-readable, full detail. Pipe to `jq`, custom dashboards. |
| `github` | `::error::` / `::warning::` annotations on the GitHub PR diff. |
| `sarif` | GitHub Code Scanning, Azure DevOps, any SARIF v2.1.0 consumer. |
| `dot` | Graphviz module dependency graph. |
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the format summary table, dot is described as a "module dependency graph", but --format dot currently emits a function call graph (see src/adapters/report/dot.rs). Please update this row so users don’t expect a coupling/module graph from dot.

Suggested change
| `dot` | Graphviz module dependency graph. |
| `dot` | Graphviz function call graph. |

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +73
::error file=src/order.rs,line=48,title=IOSP::function mixes orchestration with logic
::warning file=src/utils/legacy.rs,line=12,title=DRY-002::dead code
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The github format example uses title= and shows an ::error annotation for an IOSP violation, but the implementation emits ::warning file=...,line=...::... for individual IOSP violations and does not set title=. Please update the example to match src/adapters/report/github.rs / github_annotations.rs.

Suggested change
::error file=src/order.rs,line=48,title=IOSP::function mixes orchestration with logic
::warning file=src/utils/legacy.rs,line=12,title=DRY-002::dead code
::warning file=src/order.rs,line=48::function mixes orchestration with logic
::warning file=src/utils/legacy.rs,line=12::dead code

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +17
| Key | Default | Meaning |
|---|---|---|
| `ignore_functions` | `["main", "run", "visit_*"]` | Function names (or `prefix*` patterns) excluded from all dimensions |
| `exclude_files` | `[]` | Glob patterns for files to skip entirely |
| `strict_closures` | `false` | Treat closures as logic (stricter IOSP) |
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documented default for ignore_functions doesn’t match actual config defaults. Config::default() uses an empty list, and rustqual --init generates ["main", "test_*"] (not run / visit_*). Please update the "Default" column to reflect either the serde default (when omitted) or clearly label these as recommended starter values.

Copilot uses AI. Check for mistakes.
Comment on lines +23 to +26
```toml
ignore_functions = ["main", "run", "visit_*"]
exclude_files = ["examples/**", "vendor/**"]
max_suppression_ratio = 0.05
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example snippet shows ignore_functions = ["main", "run", "visit_*"], which doesn’t match the generated starter config (--init) or the actual default when the key is omitted. Consider updating this snippet to mirror rustqual --init output (or label it as a suggested starting point, not the default).

Copilot uses AI. Check for mistakes.
Compact representations tuned for LLM consumption — fewer tokens than full JSON, focused on what an agent needs to act:

- `ai` — token-efficient text format. Findings only, with file:line, code, and a one-line description.
- `ai-json` — minimal JSON: code, file, line, function, message. No metadata, no per-file tables.
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ai-json description here says it’s a minimal JSON with code/file/line/function/message, but the actual --format ai-json output includes version, findings, and findings_by_file grouped entries (see src/adapters/report/ai.rs). Please update this bullet to reflect the real shape.

Suggested change
- `ai-json`minimal JSON: code, file, line, function, message. No metadata, no per-file tables.
- `ai-json`compact JSON for agents. Includes a top-level `version` plus grouped `findings` and `findings_by_file` entries, rather than the full general-purpose JSON report.

Copilot uses AI. Check for mistakes.
Comment thread README.md

1. **Syntactic analysis only.** Uses `syn` for AST parsing. The receiver-type-inference engine (v1.2+) resolves most method-call receivers; what it can't resolve stays unresolved rather than being fabricated.
2. **Macros.** Macro invocations are not expanded. `println!` etc. are special-cased; custom macros producing logic or calls may be misclassified. Configurable via `[architecture.call_parity].transparent_macros`.
3. **External file modules.** `mod foo;` declarations pointing to separate files are not followed. Only inline modules (`mod foo { ... }`) are analysed recursively.
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "External file modules" limitation is currently stated as a blanket rule, but rustqual does analyze external module files when run on a directory (it walks all *.rs files). Consider clarifying that external modules are only missed when you run rustqual on a single file path (vs the crate root / directory), or otherwise describe the actual limitation more precisely.

Suggested change
3. **External file modules.** `mod foo;` declarations pointing to separate files are not followed. Only inline modules (`mod foo { ... }`) are analysed recursively.
3. **External file modules.** When you run rustqual on a single `.rs` file, `mod foo;` declarations pointing to separate files are not followed from that file's AST; only inline modules (`mod foo { ... }`) are analysed recursively. When you run rustqual on a directory or crate root, it walks `*.rs` files, so those external module files are analysed.

Copilot uses AI. Check for mistakes.
Comment thread book/module-quality.md

## Self-compliance

rustqual itself runs at 100% SRP and ratchets file lengths down aggressively. The CLAUDE.md note worth knowing if you adopt the same workflow:
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section references a "CLAUDE.md" note, but the repo doesn’t include a CLAUDE.md file. Either add the referenced file/note, or rephrase this as guidance to add such a note to the adopter’s own instruction file (with an example inline).

Suggested change
rustqual itself runs at 100% SRP and ratchets file lengths down aggressively. The CLAUDE.md note worth knowing if you adopt the same workflow:
rustqual itself runs at 100% SRP and ratchets file lengths down aggressively. If you adopt the same workflow, add a note like this to your own instruction file or team guidance:

Copilot uses AI. Check for mistakes.
Comment on lines +95 to +99
## `dot`

Module dependency graph in Graphviz format:

```bash
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dot section currently describes a module dependency graph, but --format dot outputs a function call graph (nodes are function qualified names). Consider rewording this section so it matches what src/adapters/report/dot.rs actually emits.

Copilot uses AI. Check for mistakes.
Comment thread README.md
3. `RUSTFLAGS="-Dwarnings" cargo clippy --all-targets` — clippy must stay clean.
4. Update `CHANGELOG.md` for any user-visible change; bump `Cargo.toml` version on release-worthy contributions.

The codebase is its own best reference for IOSP self-compliance and the architecture rules. The CLAUDE.md file documents internal conventions and common pitfalls.
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

README references a "CLAUDE.md" file as if it exists in this repo, but there is no such file in the tree. Either add the file (and ensure it contains the referenced conventions) or reword this sentence to describe the conventions without pointing to a non-existent file.

Suggested change
The codebase is its own best reference for IOSP self-compliance and the architecture rules. The CLAUDE.md file documents internal conventions and common pitfalls.
The codebase is its own best reference for IOSP self-compliance, architecture rules, internal conventions, and common pitfalls.

Copilot uses AI. Check for mistakes.
Comment on lines +45 to +49
```jsonc
{
"version": "1.2.0",
"summary": { "score": 82.3, "functions": 24, "findings": 4, "warnings": 0,
"dimensions": { "iosp": 85.7, "complexity": 90.0, /* ... */ } },
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The --format json example schema shown here (including a top-level version and findings array) doesn’t match the implemented JSON output, which serializes a JsonOutput with summary, functions, and optional per-dimension sections (see src/adapters/report/json.rs and json_types.rs). Please update the snippet + the jq examples to use the real field names/shape.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants